<template>
    <el-col :span="span">
        <div class="chart-container">
            <div class="function-area">
                <div class="left">
                    <el-form label-width="70px" inline>
                        <el-form-item>
                            <el-select
                                v-model="metric"
                                placeholder="请选择模式"
                                style="width: 150px"
                            >
                                <el-option
                                    v-for="item in metricOptions"
                                    :key="item"
                                    :value="item"
                                ></el-option>
                                <!-- <el-option value="ACC"></el-option>
                                <el-option value="RMSE"></el-option>
                                <el-option value="BIAS"></el-option> -->
                            </el-select>
                        </el-form-item>
                        <!-- 日期选择——单日 -->
                        <el-form-item label="日期" label-width="60px" v-show="timeMode == '单日'">
                            <el-select v-model="date" placeholder="请选择日期" style="width: 150px" no-data-text="已勾选模式无共有日期">
                                <el-option v-for="item in modeDateOptions" :key="item" :value="item">
                                </el-option>
                            </el-select>
                        </el-form-item>
                        <!-- 日期选择——时间集成与时间序列 -->
                        <el-form-item label="日期" v-show="timeMode != '单日'">
                            <el-select
                                v-model="startDate"
                                placeholder="请选择开始日期"
                                style="width: 150px"
                                @change="datechange"
                                no-data-text="已勾选模式无共有日期"
                            >
                                <el-option v-for="item in modeDateOptions" :key="item" :value="item">
                                </el-option>
                            </el-select>
                            <span style="padding: 0 15px">到</span>
                            <el-select
                                v-model="endDate"
                                placeholder="请选择结束日期"
                                style="width: 150px"
                                @change="datechange"
                                no-data-text="已勾选模式无共有日期"
                            >
                                <el-option v-for="item in modeDateOptions" :key="item" :value="item">
                                </el-option>
                            </el-select>
                        </el-form-item>
                        <!-- 高度高度选择——单日 -->
                        <el-form-item label="">
                            <el-select
                                v-model="level"
                                placeholder="请选择高度"
                                style="width: 110px;"
                            >
                                <el-option
                                    v-for="item in levelOptions"
                                    :key="item.value"
                                    :value="item.value"
                                    :label="item.label"
                                >
                                    <span style="float: left">{{ item.value }}</span>
                                    <span style="float: right; color: #8492a6; font-size: 13px"
                                        >hPa</span
                                    >
                                </el-option>
                            </el-select>
                        </el-form-item>
                        <!-- 时间序列 -->
                        <el-form-item label="时效" v-show="timeMode == '时间序列'">
                            <el-select
                                v-model="aging"
                                placeholder="请选择时间"
                                style="width: 100px;"
                            >
                                <el-option
                                    v-for="item in agingOptions"
                                    :key="item.value"
                                    :value="item.value"
                                    :label="item.label"
                                >
                                    <span style="float: left">{{ item.value }}</span>
                                    <span style="float: right; color: #8492a6; font-size: 13px"
                                        >H</span
                                    >
                                </el-option>
                            </el-select>
                        </el-form-item>
                        <el-form-item v-if="chartsVisable">
                            <el-button type="primary" plain @click="startChartDraw">刷新图表</el-button>
                        </el-form-item>
                        <el-form-item>
                            <el-button type="danger"
                                round
                                @click="$emit('delete-chart', [id])"
                                v-if="timeMode == '单日'"
                            >删除本图表</el-button>
                        </el-form-item>
                    </el-form>

                    <!-- <coordinate-picker v-model="area"></coordinate-picker> -->
                    <!-- 可选区域 -->
                    <el-form>
                        <el-form-item>
                            <el-select
                                class="area-select"
                                v-model="area"
                                placeholder="可选区域"
                                clearable
                            >
                                <el-option
                                    v-for="item in areaOptions"
                                    :key="item.value"
                                    :value="item.value"
                                    :label="item.label"
                                ></el-option>
                            </el-select>
                        </el-form-item>
                    </el-form>

                    <el-checkbox-group v-model="mode">
                        <el-checkbox
                            v-for="item in modeOptions"
                            :key="item"
                            :label="item"
                        ></el-checkbox>
                    </el-checkbox-group>
                </div>

                <div class="output">
                    <span>图表导出：</span>
                    <el-popover
                        placement="bottom"
                        width="160"
                        v-model="outputVisible"
                    >
                        <span>请选择绘制分辨率比例</span>
                        <el-select v-model="pixelRatio" size="mini" style="margin: 5px 0;">
                            <el-option value="1" label="1（模糊，不推荐）"></el-option>
                            <el-option value="2"></el-option>
                            <el-option value="3"></el-option>
                        </el-select>
                        <div style="text-align: right; margin: 0">
                            <el-button type="primary" size="mini" @click="output('PNG')">确定</el-button>
                        </div>
                        <el-link slot="reference" class="outputbutton" type="info">PNG</el-link>
                    </el-popover>
                    <el-link class="outputbutton" type="info" @click="output('SVG')">SVG</el-link>
                </div>
            </div>

            <div class="drawing-board">
                <div class="status" v-show="!chartsVisable">
                    <a @click="startChartDraw">
                        <img :src="imgBrush" height="100" />
                        <div>
                            <span>开始绘制</span>
                            <span>start drawing</span>
                        </div>
                    </a>
                </div>

                <div v-show="chartsVisable" :id="id" class="chart" v-loading="loading"></div>
                <div :id="id+'svg'" class="chart-svg"></div>
            </div>
        </div>
    </el-col>
</template>

<script>
import imgBrush from "@/assets/img/brush.svg";
import "@/assets/echarts-customize";
import {drawingRequest as global_deterministic} from '@/api/globalDeterm/globalDeterm.js'
import {drawingRequest as grapes_region_determ} from '@/api/grapesRegionDeterm/grapesRegionDeterm.js'
const mods = {global_deterministic, grapes_region_determ}

export default {
    name: "Charts",
    props: {
        // 时间模式 - 单日，时间序列，时间集成
        timeMode: String,
        // 分析检验目标 - h, t, u, v, w
        shortname: String,
        // 日期选项
        dateOptions: {
            type: Object,
            default() {
                return {};
            },
        },
        // 模式选项
        modeOptions: {
            type: Array,
            default() {
                return [];
            },
        },
        id: String,
        windowWidth: Number,
    },
    data() {
        return {
            // 误差模式
            metric: "BIAS",
            // 误差模式选项
            metricOptions: [],
            // 单日日期
            date: "",
            // 时间序列起止日期
            startDate: "",
            pre_startDate: "",
            endDate: "",
            pre_endDate: "",
            // 高度值
            level: "",
            // 高度值选项
            levelOptionsValue: [],
            // 时效选项
            aging: "",
            agingOptionsValue: [],
            // 区域设置
            area: '',
            // 区域选项
            areaOptions: [],
            // 绘制选项
            mode: [],
            // 图表显示
            chartsVisable: false,
            // echarts模块
            echarts: null,
            // chart实例
            chartObject: null,
            // chart标题
            chartTitle: "",
            // chart基础设置
            chartOptions: {},
            // 图表导出对话框
            outputVisible: false,
            // 图表绘制分辨率比例
            pixelRatio: 1,
            // 开始绘制按钮图片
            imgBrush,
            // 组件占位个数
            span: 24,
            // Loading动画
            loading: false,
        };
    },
    mounted() {
        let _this = this;

        this.$nextTick(function() {
            // 根据不同模块显示误差模式选项、高度值选项、可选区域、时效选项
            if(_this.path[1] === 'grapes_region_determ') {
                _this.metricOptions = ['BIAS', 'RMSE', 'STD']
                _this.levelOptionsValue = [100, 200, 300, 400, 500, 700, 850, 1000]
                _this.areaOptions = [{value: 'China', label: 'China (15-60, 70-145)'}]
                _this.area = 'China'
                _this.agingOptionsValue = [24, 48, 72]
            }
            else {
                _this.metricOptions = ['ACC', 'RMSE', 'BIAS']
                _this.levelOptionsValue = [1, 3, 5, 10, 50, 70, 100, 250, 300, 400, 500, 700, 850, 1000]
                _this.areaOptions = [
                    {value: 'NHEM', label: 'NHEM'},
                    {value: 'SHEM', label: 'SHEM'},
                    {value: 'EASI', label: 'EASI'},
                    {value: 'TROP', label: 'TROP'},
                    {value: 'GLOB', label: 'GLOB'},
                ]
                _this.area = 'NHEM'
                _this.agingOptionsValue = [4, 8, 12, 16, 20, 24, 28, 32, 36]
            }
            
            // 默认选择所有模式
            _this.mode = _this.modeOptions
            // 单日日期初始化
            // _this.date = _this.modeDateOptions[0];
            // 时间序列起止日期初始化
            // _this.startDate = _this.pre_startDate = _this.modeDateOptions[0];
            // _this.endDate = _this.pre_endDate = _this.modeDateOptions.slice(-1)[0];
            // 高度值初始化
            _this.level = _this.levelOptions[0].value;
            // 时效值初始化
            _this.aging = _this.agingOptions[0].value;
            this.redrawChart();
            
            // 引入 ECharts 主模块
            this.echarts = require("echarts/lib/echarts");
            // 引入柱状图
            require("echarts/lib/chart/bar");
            // 引入折线图
            require("echarts/lib/chart/line");
            // 引入提示框
            require("echarts/lib/component/tooltip");
            // 引入图表标题
            require("echarts/lib/component/title");
            // 引入图例
            require("echarts/lib/component/legend");
            // 引入工具箱
            require("echarts/lib/component/toolbox");
        });
    },
    computed: {
        // 日期选项预处理，取所选模式对应日期的交集
        modeDateOptions(){
            let _this = this
            // 拷贝一份数组
            let modeSelected = this.mode.slice()
            // 检查是否有选中模式
            if(modeSelected.length!==0){
                // 取出第一个选中的第一个模式
                let result = _this.dateOptions[modeSelected.shift()]
                // 让第一个模式对应的时间数组不断与其他模式取交集
                if(result){
                    for(let prop of modeSelected){
                        result = result.filter(element => {
                            return _this.dateOptions[prop].indexOf(element) > -1
                        });
                    }

                    // 单日日期初始化
                    _this.date = result[0];
                    // 时间序列起止日期初始化
                    _this.startDate = _this.pre_startDate = result[0];
                    _this.endDate = _this.pre_endDate = result.slice(-1)[0];
                    return result
                }else return []
            }else {
                // 单日日期初始化为空
                _this.date = null;
                // 时间序列起止日期初始化为空
                _this.startDate = _this.pre_startDate = null;
                _this.endDate = _this.pre_endDate = null;
                return []
            }
        },
        // 高度选项预处理
        levelOptions() {
            const _this = this;
            let levelOptions = [];
            for (let item of _this.levelOptionsValue)
                levelOptions.push({ value: item, label: item + " hPa" });
            return levelOptions;
        },
        // 时效选项预处理
        agingOptions() {
            const _this = this;
            let agingOptions = [];
            for (let item of _this.agingOptionsValue)
                agingOptions.push({ value: item, label: item + "H" });
            return agingOptions;
        },
        // 请求绘图数据时使用的参数
        selections() {
            const {
                shortname,
                level,
                mode,
                modeDateOptions,
                date,
                startDate,
                endDate,
                aging,
                metric,
                area,
                timeMode,
            } = this;
            const selections = {
                shortname, level, mode,
                isDateRange: timeMode == "单日" ? false : true,
                isTimeseries: timeMode == "时间序列" ? true : false, 
                aging, date,
                datesList: modeDateOptions.slice(modeDateOptions.indexOf(startDate), modeDateOptions.indexOf(endDate)+1),
                metric, area
            };
            return selections;
        },
        // 路由参数
        path() {
            return this.$route.path.split("/");
        },
    },
    watch: {
        // selections: "resetChart",
        windowWidth: "redrawChart",
    },
    methods: {
        // ECharts初始化
        setCharts() {
            // 基于准备好的dom，初始化echarts实例
            this.chartObject = this.echarts.init(document.getElementById(this.id), "macarons");

            // 标题生成
            switch(this.timeMode){
                case '单日':
                    this.chartTitle = [this.metric, this.date, `${this.level}hPa`, this.area].join('_')
                    break
                case '时间集成':
                    this.chartTitle = [this.metric, `${this.startDate} - ${this.endDate}`, this.area].join('_')
                    break
                case '时间序列':
                    this.chartTitle = [this.metric, `${this.startDate} - ${this.endDate}`, `${this.aging}H`, this.area].join('_')
                    break
            }

            // 图表结构配置
            this.chartOptions = {
                title: {
                    subtext: this.chartTitle,
                    left: "center",
                },
                tooltip: {},
                // 工具箱内容
                toolbox: {
                    itemSize: 20,
                    feature: {
                        magicType: {
                            type: ["line", "bar"],
                        },
                        dataView: {
                            show: true,
                            // readOnly: true
                        },
                    },
                },
                // X轴内容
                xAxis: {
                    data: [],
                },
                yAxis: {},
                grid: {
                    bottom: 40,
                    top: 50,
                    left: 60,
                    right: 30,
                },
            }
        },
        // 绘制开始
        startChartDraw() {
            const _this = this;
            // 先重置图表
            _this.resetChart();

            let emptyAreaFlag = true; // 区域选择空标志
            let emptymodeflag = true; // 模式空标志
            let emptyDateflag = true; // 时间选项空标志
            if(_this.selections.isDateRange && _this.selections.datesList.length===0) emptyDateflag = false;
            if(!_this.selections.isDateRange && _this.selections.date===undefined) emptyDateflag = false;
            if(_this.selections.area === '') emptyAreaFlag = false; // 判断区域是否为空 
            if(_this.selections.mode.length === 0) emptymodeflag = false; //判断模式选择是否为空
            
            // 获取图表绘制数据
            if (emptyAreaFlag && emptymodeflag && emptyDateflag) {
                // 显示图表绘制div
                _this.chartsVisable = true;
                // 启动加载动画
                _this.loading = true;

                // 等待dom树更新后开始绘制图表基础部分
                _this.$nextTick(() => {
                    _this.setCharts(); //开始绘制
                });
                // 从后端获取数据
                mods[_this.path[1]](
                    _this.path[2].indexOf("bufer")!==-1
                    ? "station_analyze"
                    : "grid_analyze", _this.selections)
                    .then((res) => {
                        let series = [];
                        for (let index in res.data.data_y)
                            series.push({
                                type: "line",
                                name: _this.selections.mode[index],
                                data: res.data.data_y[index].map((currentVal) => {
                                    return currentVal == -9999 ? null : currentVal
                                })
                            });

                        const chartOptions = {
                            legend: {
                                data: _this.selections.mode,
                                left: 10,
                            },
                            xAxis: {
                                data: _this.selections.isDateRange ? res.data.data_x[0] : res.data.data_x[0].map((current) => {
                                    return current + "H";
                                }),
                            },
                            series: series,
                        };
                        console.log(`${_this.path[2].indexOf("bufer")!==-1 ? "站点绘制数据" : "格点绘制数据"}`, chartOptions);
                        this.chartOptions.xAxis = chartOptions.xAxis;
                        this.chartOptions.series = chartOptions.series;
                        this.chartOptions.legend = chartOptions.legend;
                        // 绘制图表
                        _this.chartObject.setOption(this.chartOptions);
                        // 结束loading动画
                        setTimeout(() => {
                            _this.loading = false;
                        }, 100);
                    });
            } else {
                _this.loading = false;
                
                if(!emptyAreaFlag) _this.$message.warning('区域选择为空，请选择区域')
                
                setTimeout(()=>{
                    if (!emptymodeflag) _this.$message.warning('模式选项为空，请至少选择一个模式')
                }, 0)
                
                setTimeout(()=>{
                    if (!emptyDateflag) _this.$message.warning('时间选择不能为空，请切换选择模式以保证时间选项不为空')
                }, 0)
            }
        },
        // 图表重置
        resetChart() {
            document.getElementById(this.id).removeAttribute("_echarts_instance_");
            document.getElementById(this.id).innerHTML = "";
            document.getElementById(this.id+'svg').removeAttribute("_echarts_instance_");
            document.getElementById(this.id+'svg').innerHTML = "";
            this.chartsVisable = false;
        },
        // 图表重新绘制
        redrawChart() {
            let _this = this;

            if (_this.chartObject) _this.chartObject.resize();
        },
        // 日期选择后的判断逻辑
        datechange(current) {
            if (this.startDate >= this.endDate) {
                this.startDate = this.pre_startDate;
                this.endDate = this.pre_endDate;
                this.$message({
                    message: "日期范围选择错误，请重新选择",
                    type: "error",
                });
            } else {
                this.pre_startDate = this.startDate;
                this.pre_endDate = this.endDate;
            }
        },
        // 图片导出
        output(type) {
            if (this.chartObject) {
                this.dialogOutputVisible = true;
                if (type == "PNG") {
                    
                    // 获取到的是一串base64信息
                    let picInfo = this.chartObject.getDataURL({
                        type: "png",
                        pixelRatio: this.pixelRatio,
                        backgroundColor: "#fff",
                        excludeComponents: ["toolbox"],
                    });

                    const elink = document.createElement("a");
                    elink.download = this.chartTitle + ".png";
                    elink.style.display = "none";
                    elink.href = picInfo;
                    document.body.appendChild(elink);
                    elink.click();
                    URL.revokeObjectURL(elink.href); // 释放URL 对象
                    document.body.removeChild(elink);
                } else if (type == "SVG") {
                    let echartContainer = document.getElementById(this.id + 'svg');
                    let echartsInstance = this.echarts.init(echartContainer, "macarons", {renderer: 'svg'});
                    echartsInstance.setOption(this.chartOptions);

                    // 若使用svg渲染，此处获得的图像数据为svg
                    let svgInfo = echartsInstance.getDataURL({
                        type: "png",
                        pixelRatio: 1,
                        backgroundColor: "#fff",
                        excludeComponents: ["toolbox"],
                    });

                    const elink = document.createElement("a");  // 创建a标签用于下载
                    elink.download = this.chartTitle + ".svg";
                    elink.style.display = "none";
                    elink.href = svgInfo;
                    document.body.appendChild(elink);
                    elink.click();
                    URL.revokeObjectURL(elink.href);    // 释放URL对象
                    document.body.removeChild(elink);   // 移除a标签
                }
            } else {
                this.$message({
                    message: "暂未绘制图表，请先绘制图表",
                    type: "error",
                });
            }
        },
    },
};
</script>

<style lang="scss" scoped>
@import "@/assets/css/DFcontent.scss";
.drawing-board {
    height: 400px;
}
</style>
